package secondriver.springsubway.example.aop.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.DeclareParents;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;

import secondriver.springsubway.example.aop.demo.Tester;
import secondriver.springsubway.example.aop.demo.TesterImpl;

/**
 * 新 @Aspectj 形式的Spring AOP
 * 
 * <p>
 * 可以将公共的Pointcut抽取到一个Aspectj中其它要用到Pointcut则通过packagename.aspectj.
 * PointcutName引用即可.
 * </p>
 * 
 * @author secondriver
 * @created 2015-5-7 下午2:25:19
 * 
 */
@Aspect
public class SimpleTraceMethodAspect implements Ordered {

	/**
	 * 这里的value值指定目标对象或者一组目标对象
	 */
	@DeclareParents(value = "secondriver.springsubway.example.aop.demo.DeveloperImpl", defaultImpl = TesterImpl.class)
	public Tester tester;

	@Pointcut(value = "execution(public String secondriver.springsubway.example.aop..*.do*(..))")
	public void doMethod() {
	}

	@Pointcut("execution(public boolean secondriver.springsubway.example..*.isBusy())")
	public void isMethod() {
	}

	@Around(value = "doMethod()")
	public Object traceMethod(ProceedingJoinPoint joinPoint) throws Throwable {
		String info = joinPoint.getTarget().getClass().getCanonicalName() + "."
				+ joinPoint.getSignature().getName();
		System.out.println("start:" + info);
		Object result = joinPoint.proceed();
		System.out.println("trace result:" + result);
		System.out.println("end:" + info);
		return result;
	}

	@AfterReturning(value = "isMethod()", returning = "retval")
	public void afterPrint(boolean retval, JoinPoint joinPoint) {
		String info = joinPoint.getSignature().getDeclaringTypeName() + "."
				+ joinPoint.getSignature().getName();
		System.out.println("afterReturning " + info);
		System.out.print("isBusy? ");
	}

	// @Pointcut(value =
	// "within(secondriver.springsubway.example.aop.demo.TesterImpl)")
	// // 匹配指定类型下的所有Joinpoint
	// public void beforeWithAllMethod() {
	// }
	//
	// @Before("beforeWithAllMethod()")
	// public void beforeWithin(JoinPoint joinPoint) {
	// String info = joinPoint.getSignature().getDeclaringTypeName() + "."
	// + joinPoint.getSignature().getName();
	// System.out.println("execution before:" + info);
	// }

	@Before(value = "args(name) && execution(public void secondriver.springsubway.example.aop..*.say(String))")
	public void beforeSay(JoinPoint joinPoint, String name) {
		System.out.println("I get " + joinPoint.getSignature().getName()
				+ " method argument args0=" + name);
	}

	/**
	 * 与Adivce执行顺序相关主题
	 * 
	 * @see org.springframework.core.Ordered#getOrder()
	 */
	@Override
	public int getOrder() {
		return 9;
	}
}
